//
//  FyUILib.m
//  FyUILib
//
//  Created by luoc on 16/2/6.
//  Copyright © 2016年 luoc. All rights reserved.
//
#import <JavaScriptCore/JavaScriptCore.h>
#import "UIManager.h"
#import "CXmlParse.h"
#import "BaseViewController.h"
static NSString  *gLanguageFile = nil;
@interface UIManager()
{
    NSMutableArray              *_array;
    NSMutableArray              *_floatArray;
    NSMutableArray              *_groupOption;
    UIViewController<UIManagerDelegate>       *_pController;
    JSContext                   *_context;
    NSMutableArray              *_jsFilesArray;
    NSString                    *_lanFile;
}
@end

@implementation UIManager
@synthesize mainView;
- (id)initWithUIManagerDelegate:(UIViewController<UIManagerDelegate>*)pController{
    self = [super init];
    if (self) {
        _array = [[NSMutableArray alloc] init];
        _pController = pController;
        _floatArray = [[NSMutableArray alloc] init];
        _groupOption = [[NSMutableArray alloc] init];
        
        _context = nil;
        _jsFilesArray = nil;
        
        _lanFile = gLanguageFile;
    }
    return self;
}

- (void)ReloadTextInfoWithView:(UIView*) view
{
    for (UIView* v in view.subviews) {
        [self ReloadTextInfoWithView:v];
        if ([[NSStringFromClass([v class]) substringToIndex:1] isEqualToString:@"C"]){
            id<UIAttribute> pElem = (id<UIAttribute>)v;
            [[pElem commonFun] ChangeTextInfo];
        }
    }
}

- (void)ReloadTextInfo
{
    if (!_lanFile || !gLanguageFile || [_lanFile isEqualToString:gLanguageFile]) {
        return;
    }
    _lanFile = gLanguageFile;
    [self ReloadTextInfoWithView:mainView];
}

+ (NSString*)getTextOfLanguageTag:(NSString*)lgTag
{
    return [[CXmlParse sharedXmlParse:gLanguageFile] GetValue:lgTag];
}

+ (void)ReloadLoadLanguage:(NSString*)sFile
{
    if (![sFile isEqualToString:gLanguageFile]) {
        [CXmlParse releasXmlParse];
    }
    gLanguageFile = sFile;
    [CXmlParse sharedXmlParse:sFile];
}

- (void)dealloc
{
    if (_array) {
        [_array removeAllObjects];
    }
    if (_floatArray) {
        [_floatArray removeAllObjects];
    }
    if (_groupOption) {
        [_groupOption removeAllObjects];
    }
    if (_jsFilesArray) {
        [_jsFilesArray removeAllObjects];
    }
    if (mainView) {
        [mainView removeFromSuperview];
    }
    _array = nil;
    _pController = nil;
    _floatArray = nil;
    _groupOption = nil;
    _context = nil;
    _jsFilesArray = nil;
    mainView = nil;
}

- (UIViewController<UIManagerDelegate>*)mainController
{
    return _pController;
}

- (void)addJsFile:(const char*)file
{
    NSString *f = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:file] ofType:@"js"];
    FILE* fp = fopen([f UTF8String], "rb");
    if (fp) {
        fseek(fp, 0, SEEK_END);
        int len = (int)ftell(fp);
        fseek(fp, 0, SEEK_SET);
        char* pBuf = (char*)malloc(len+1);
        int r = (int)fread(pBuf, 1, len, fp);
        if (r == len) {
            pBuf[r] = 0;
            NSString* str = [NSString stringWithUTF8String:pBuf];
            [_context evaluateScript:str];
        }
        free(pBuf);
        fclose(fp);
    }
}

- (void)initJs
{
    if (_context) {
        return;
    }
    _jsFilesArray = [[NSMutableArray alloc] init];
    _context = [[JSContext alloc] init];
    __weak typeof(UIManager*) weakSelf = self;
    _context[@"getViewOfName"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* name = [array objectAtIndex:0];
        return [weakSelf GetViewOfName:[[name toString] UTF8String]];
    };
    
    _context[@"log"] = ^(){
        NSArray* array = [JSContext currentArguments];
        for (id o in array) {
            NSLog(@"%@", o);
        }
    };
    
    _context[@"setAttr"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* obj = [array objectAtIndex:0];
        JSValue* attr = [array objectAtIndex:1];
        JSValue* val = [array objectAtIndex:2];
        id<UIAttribute> o = (id<UIAttribute>)[obj toObject];
        [o SetAttribute:[[attr toString] UTF8String] :[[val toString] UTF8String]];
    };
    
    _context[@"setAttr2"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* obj = [array objectAtIndex:0];
        JSValue* attr = [array objectAtIndex:1];
        JSValue* val = [array objectAtIndex:2];
        id<UIAttribute> o = (id<UIAttribute>)[weakSelf GetViewOfName:[[obj toString] UTF8String]];
        [o SetAttribute:[[attr toString] UTF8String] :[[val toString] UTF8String]];
    };
    
    _context[@"endEditing"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* obj = [array objectAtIndex:0];
        JSValue* val = [array objectAtIndex:1];
        
        UIView* o = (UIView*)[obj toObject];
        [o endEditing:[val toBool]];
    };
    
    _context[@"animate"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* fun = [array objectAtIndex:0];
        JSValue* tm = [array objectAtIndex:1];
        [UIView animateWithDuration:[tm toDouble] animations:^{
            [fun callWithArguments:nil];
        }];
    };
    
    _context[@"needDisplay"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* obj = [array objectAtIndex:0];
        UIView* o = (UIView*)[obj toObject];
        [o setNeedsDisplay];
    };
    
    _context[@"setHidden"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* obj = [array objectAtIndex:0];
        JSValue* val = [array objectAtIndex:1];
        UIView* o = (UIView*)[obj toObject];
        [o setHidden:[val toBool]];
    };
    
    __weak typeof(UIViewController*) weakController = _pController;
    _context[@"pushViewController"] = ^(){
        NSArray* array = [JSContext currentArguments];
        JSValue* val = [array objectAtIndex:0];
        CBaseViewController* vc = [[CBaseViewController alloc] initWithXml:[val toString]];
        [weakController.navigationController pushViewController:vc animated:YES];
    };
    _context[@"popViewController"] = ^(){
        [weakController.navigationController popViewControllerAnimated:YES];
    };
}

- (id)init{
    self = [super init];
    if (self) {
        _pController = nil;
        _array = [[NSMutableArray alloc] init];
        _floatArray = [[NSMutableArray alloc] init];
        _groupOption = [[NSMutableArray alloc] init];
        
        _lanFile = gLanguageFile;
    }
    return self;
}

- (UIView*)GetViewOfName:(const char*)name
{
    NSInteger count = [_array count];
    for (int i=0; i<count; i++) {
        NSArray* o = [_array objectAtIndex:i];
        if (strcmp([[o objectAtIndex:0] UTF8String], name) == 0) {
            return [o objectAtIndex:1];
        }
    }
    return nil;
}

- (void)AddFloatObject:(UIView*)view
{
    [_floatArray addObject:view];
}

- (void)removeFloatObject:(UIView*)view
{
    [_floatArray removeObject:view];
}

- (void)ChangeOptionSelectObject:(COptionUI*)option :(NSString*)groupName
{
    NSInteger count = [_groupOption count];
    for (int i=0; i<count; i++) {
        NSArray* o = [_groupOption objectAtIndex:i];
        if ([groupName isEqualToString:[o objectAtIndex:0]]) {
            COptionUI* obj = (COptionUI*)[o objectAtIndex:1];
            [obj setSelected:NO];
            [option setSelected:YES];
            [_groupOption removeObject:o];
            break;
        }
    }
    
    NSArray* o = [[NSArray alloc] initWithObjects:groupName, option, nil];
    [_groupOption addObject:o];
}

- (void)AddObject:(const char*)name :(UIView*)view
{
    NSArray* o = [[NSArray alloc] initWithObjects:[NSString stringWithUTF8String:name], view, nil];
    [_array addObject:o];
}

- (BOOL)OnNotify:(id<UIAttribute>)pSender event:(FYEVENT)event param:(void *)param
{
    if (_context) {
        JSValue* fun = _context[@"OnNotify"];
        if (FYEVENT_TB_SELECTED == event) {
            NSIndexPath* indexPath = (__bridge NSIndexPath*)param;
            [fun callWithArguments:[[NSArray alloc] initWithObjects:[[pSender commonFun] name], [NSNumber numberWithInteger:event], [NSNumber numberWithLong:indexPath.section], [NSNumber numberWithLong:indexPath.row], nil]];
        }else{
            [fun callWithArguments:[[NSArray alloc] initWithObjects:[[pSender commonFun] name], [NSNumber numberWithInteger:event], nil]];
        }
    }
    return [_pController OnNotify:pSender event:event param:param];
}

- (void)SetMainView:(UIView *)view{
    mainView = view;
    _context[@"gMainView"] = mainView;
}

- (void)setFloatViewNeedDisplay
{
    CGRect rt = mainView.frame;
    for (UIView* v in _floatArray) {
        id<UIAttribute> o = (id<UIAttribute>)v;
        
        [v removeFromSuperview];
        CCommonFunUI* pCommonFun = [o commonFun];
        [mainView addSubview:v];
        CGRect rct;
        rct.size.width = rt.size.width;
        rct.size.height = rt.size.height;
        rct.origin.x = rt.origin.x;
        rct.origin.y = rt.origin.y;
        if ([pCommonFun IsHeightSet]){
            rct.size.height = v.frame.size.height;
            
            if (pCommonFun.fTop != -1.0f) {
                rct.origin.y = pCommonFun.fTop;
            }else if (pCommonFun.fBottom != -1.0f) {
                rct.origin.y = rt.size.height - rct.size.height - pCommonFun.fBottom;
            }
        }else{
            if (pCommonFun.fTop != -1.0f) {
                rct.origin.y = pCommonFun.fTop;
            }
            if (pCommonFun.fBottom != -1.0f) {
                rct.size.height -= (pCommonFun.fBottom - rct.origin.y);
            }
        }
        
        if ([pCommonFun IsWidthSet]) {
            rct.size.width = v.frame.size.width;
            
            if (pCommonFun.fLeft != -1.0f) {
                rct.origin.x = pCommonFun.fLeft;
            }else if (pCommonFun.fRight != -1.0f) {
                rct.origin.x = rt.size.width - rct.size.width - pCommonFun.fRight;
            }
        }else{
            if (pCommonFun.fLeft != -1.0f) {
                rct.origin.x = pCommonFun.fLeft;
            }
            
            if (pCommonFun.fRight != -1.0f) {
                rct.size.width -= (pCommonFun.fRight + rct.origin.x);
            }
        }
        [v setFrame:rct];
    }
}
@end
